<?php

namespace App\Model\Dao;

use App\Model\Enum\OrderDetailDisEnum;
use App\Model\Enum\OrderDetailFrozenEnum;
use App\Model\Enum\OrderDetailRefundEnum;
use App\Model\Enum\OrderDetailThawEnum;
use App\Utils\CustomUtils;
use App\Concern\BaseDao;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Arr;
use Redis;
use App\Utils\RedisUtils;
use Hyperf\Utils\Codec\Json;

/**
 * TradeOrderDetailDao
 */
class TradeOrderDetailDao extends BaseDao {

    /**
     * 表名常量
     * 联表的时候通过XxxDao::TABLE获取
     */
    const TABLE = "trade_order_detail";

    // 不支持软删除
    protected $softDelete = null;

    /**
     * 父类中通过静态函数获取表名, 因为不能通过静态常量获取, 这个函数是固定写在子类中的
     */
    public static function table (): string {
        return self::TABLE;
    }

    /**
     * @return \Hyperf\Database\Model\Model|null|object|static
     * 根据单号
     */
    public function getByTradeNo ($tradeNo) {
        $builder = DB::table(self::table())->where("tradeNo", $tradeNo);
        $data    = $builder->first();
        return $data;
    }

    /**
     * 排序
     *
     * @param Builder $builder
     * @param array   $params
     *
     * @return Builder|mixed
     */
    protected function _buildOrder (Builder $builder, $params = []) {

        $builder->orderBy("main.tradeNo", "desc");

        return parent::_buildOrder($builder, $params);
    }

    /**
     * 查询条件
     *
     * @param $params
     *
     * @return Builder
     */
    protected function _buildQueryString ($params) {

        // 本表一律命名为main
        $main  = sprintf("%s AS main", self::TABLE);
        $admin = sprintf("%s AS admin", SysAdminDao::TABLE);

        $builder = DB::table($main)->leftJoin($admin, "main.salesId2", "=", "admin.id");

        // 通过 Arr::exists 来判断是否存在该键, isset不准确
        (Arr::exists($params, "mchIdList") && !empty($params["mchIdList"])) && $builder->whereIn("main.mchId", $params['mchIdList']);
        (Arr::exists($params, "mchId") && $params["mchId"] !== "") && $builder->where("main.mchId", $params['mchId']);
        (Arr::exists($params, "mchNo") && $params["mchNo"] !== "") && $builder->where("main.mchNo", "like", "%{$params['mchNo']}%");
        (Arr::exists($params, "tradeNo") && $params["tradeNo"] !== "") && $builder->where("main.tradeNo", "like", "%{$params['tradeNo']}%");
        (Arr::exists($params, "orderNo") && $params["orderNo"] !== "") && $builder->where("main.orderNo", "like", "%{$params['orderNo']}%");
        (Arr::exists($params, "relNo") && $params["relNo"] !== "") && $builder->where("main.relNo", "like", "%{$params['relNo']}%");
        (Arr::exists($params, "mchUrl") && $params["mchUrl"] !== "") && $builder->where("main.mchUrl", "like", "%{$params['mchUrl']}%");
        (Arr::exists($params, "transStatus") && $params["transStatus"] !== "") && $builder->where("main.transStatus", "=", $params['transStatus']);
        (Arr::exists($params, "isSettle") && $params["isSettle"] !== "") && $builder->where("main.isSettle", "=", $params['isSettle']);
        (Arr::exists($params, "isRefund") && $params["isRefund"] !== "") && $builder->where("main.isRefund", "=", $params['isRefund']);
        (Arr::exists($params, "isDis") && $params["isDis"] !== "") && $builder->where("main.isDis", "=", $params['isDis']);
        (Arr::exists($params, "isFrozen") && $params["isFrozen"] !== "") && $builder->where("main.isFrozen", "=", $params['isFrozen']);
        (Arr::exists($params, "isThaw") && $params["isThaw"] !== "") && $builder->where("main.isThaw", "=", $params['isThaw']);
        (Arr::exists($params, "channelId") && $params["channelId"] !== "") && $builder->where("main.channelId", "=", $params['channelId']);
        (Arr::exists($params, "createTimeRange") && $params["createTimeRange"] !== "") && $builder->whereBetween('main.createTime', $params['createTimeRange']);

        $builder->selectRaw(join(",", [
            "main.*",
            "admin.username as salesName",
        ]));
        return $builder;
    }

    public function handleFrozen ($id, $isFrozen, $frozenAmount) {

        $update = [
            'isFrozen' => $isFrozen,
        ];

        if ($isFrozen == 4) {
            $update['isThaw']       = 0;
            $update['frozenAmount'] = Db::raw("`frozenAmount` + {$frozenAmount}");
        }

        return $this->update($id, $update);
    }

    public function handleThaw ($id, $isThaw, $thawAmount) {

        $update = [
            'isThaw' => $isThaw,
        ];

        if ($isThaw == 4) {
            $update['frozenAmount'] = 0;
            $update['isFrozen']     = 0;
            $update['thawAmount']   = Db::raw("`thawAmount` + {$thawAmount}");
        }

        return $this->update($id, $update);
    }

    public function handleDis ($id, $isDis, $disAmount) {

        $update = [
            'isDis' => $isDis,
        ];

        if ($isDis == 4) {
            $update['disAmount'] = Db::raw("`disAmount` + {$disAmount}");
        }

        return $this->update($id, $update);
    }

    public function handleRefund ($id, $isRefund, $refundAmount, $refundSettleAmount) {

        $update = [
            'isRefund' => $isRefund,
        ];

        if ($isRefund == 4) {
            $update['refundAmount']       = Db::raw("`refundAmount` + {$refundAmount}");
            $update['refundSettleAmount'] = Db::raw("`refundSettleAmount` + {$refundSettleAmount}");
        }

        return $this->update($id, $update);
    }

    /**
     * 订单强制成功
     *
     * @param $id
     * @param $forceSuccessStatus
     * @param $amount
     *
     * @return int
     */
    public function handleForceSuccess ($id, $forceSuccessStatus, $amount) {

        $update = [
            'forceSuccessStatus' => $forceSuccessStatus,
        ];

        if ($forceSuccessStatus == 4) {
            $update['transStatus'] = 6;
        }

        return $this->update($id, $update);
    }

    public function getDisRateList ($param, $page, $limit) {

        $mch    = sprintf('%s AS mch', MchInfoDao::TABLE);
        $detail = sprintf('%s AS detail', TradeOrderDetailDao::TABLE);

        $builder = Db::table($mch);

        $builder->join($detail, 'detail.mchId', 'mch.id');

        $builder->orderBy('mch.mchNo', 'desc');

        $builder->groupBy(['mch.mchNo']);

        $builder->selectRaw(join(',', [
            'mch.id',
            'mch.mchNo',
            'mch.mchName',
            // 总成交订单数
            'COUNT(true) AS totalSuccessCount',
            // 总拒付订单数
            'COUNT(IF(detail.isDis = 4, true, null)) AS totalDisCount',
            // 总退款订单数
            'COUNT(IF(detail.isRefund = 4, true, null)) AS totalRefundCount',
        ]));

        $builder->where('detail.isSettle', 2);
        $builder->where('detail.transStatus', 6);

        Arr::exists($param, 'mchNo') && $builder->where('mch.mchNo', $param['mchNo']);
        Arr::exists($param, 'mchName') && $builder->where('mch.mchName', 'like', "%{$param['mchName']}%");
        Arr::exists($param, 'mchIdList') && $builder->whereIn('mch.id', $param['mchIdList']);

        $total = $builder->count();

        $builder = $this->_buildPageLimit($builder, $page, $limit);
        $list    = $builder->get()->toArray();

        return ['list' => $list, 'total' => $total];
    }

    public function getSalesAmountList ($param) {

        $detail = sprintf('%s AS detail', TradeOrderDetailDao::TABLE);

        $builder = Db::table($detail);

        $builder->where('detail.isSettle', 2);
        $builder->where('detail.transStatus', 6);

        $builder->whereBetween('detail.settleTime', $param['settleTimeRange']);
        $builder->whereIn('detail.mchId', $param['mchIdList']);

        $builder->groupBy(['detail.settleCurrency']);
        $builder->orderBy('detail.settleCurrency', 'asc');

        $builder->selectRaw(join(',', [
            'detail.settleCurrency AS currency',
            'SUM(detail.settleAmount) AS amount',
        ]));

        return $builder->get()->toArray();
    }


}
